/*
 * File:   NinmanGame.cpp
 * Author: guilherme
 *
 * Created on April 27, 2011, 11:07 AM
 */

#include "NinmanGame.h"

int p;
int tempo;

void aumenta_p() {
    p++;
    tempo++;
    if (p > 4)
        p = 0;

}
END_OF_FUNCTION(aumenta_p);
typedef struct {
    int x, y;
} PONTO;

NinmanGame::NinmanGame(NinmanConfig conf) {

    std::list <PONTO> pilha, pilha1, pilha2, pilha3;
    int Nextmove = 0, tfruit = 0;
    powertime = 0;
    LoadPlayer();
    bool fruit = false;
    power = false;
    PONTO * Posicaoinicial= NULL;
    vida = 3;
    clear(screen);
    SAMPLE * siren = load_sample("Sound/siren.wav");

    if (player.points == 0) {
        sentido = esquerda;
        pontos = 0;
        LoadLab(GetLab(player));
        player.Pninman = procurarNinman();
        Posicaoinicial = FindGhost();
    } else {
        LoadMatriz();
        linhas = player.linhas;
        colunas = player.colunas;
        powertime = player.powertime;
        ghost = player.ghost;
        ghost1 = player.ghost1;
        ghost2 = player.ghost2;
        ghost3 = player.ghost3;
        pontos = player.points;
        sentido = player.sentido;
        power = player.power;
        vida = player.vida;
    }
    sentido2 = 0;
    LoadBitmaps(player.Ninman_color);
    LoadGhosts();
    venceu = 0;
    srand(time(NULL));
    tempo = 0;
    p = 0;
    LOCK_FUNCTION(aumenta_p); //Obrigatório trancar os timers usados
    LOCK_VARIABLE(p); //Obrigatório trancar as variáveis globais usadas nos timers
    LOCK_VARIABLE(tempo); //Obrigatório trancar as variáveis globais usadas nos timers
    Inicio();
    bool reset;
    install_int(aumenta_p, 40);
    play_sample(siren, 255, 0, 1000, true);
    while (venceu == 0) {
        DrawLab();
        Nextmove = LerMovimento(Nextmove);
        if (tempo > 4) {

            Nextmove = Mover(Nextmove);
            reset = Venceu();
            if (reset) {
                stop_sample(siren);
                ghost.x = Posicaoinicial[0].x;
                ghost.y = Posicaoinicial[0].y;
                ghost1.x = Posicaoinicial[1].x;
                ghost1.y = Posicaoinicial[1].y;
                ghost2.x = Posicaoinicial[2].x;
                ghost2.y = Posicaoinicial[2].y;
                ghost3.x = Posicaoinicial[3].x;
                ghost3.y = Posicaoinicial[3].y;
                ghost5.x = Posicaoinicial[4].x;
                ghost5.y = Posicaoinicial[4].y;
                matriz[Ninman.x][Ninman.y] = '0';
                Ninman = player.Pninman;
                matriz[Ninman.x][Ninman.y] = 'p';
                pilha.clear();
                pilha1.clear();
                pilha2.clear();
                pilha3.clear();
                sentido = esquerda;
                if (vida > 0) {
                    Inicio();
                    play_sample(siren, 255, 0, 1000, true);
                }
            }
            if (!fruit)
                tfruit++;
            if (tfruit > 100 && !fruit) {
                NewFruit();
                fruit = true;
            }
            if (fruit) {
                tfruit = tfruit - 2;
                if (tfruit <= 0)
                    DeleteFruit();
            }

            if (!power) {
                pilha = MoverFantasma(pilha);
                pilha1 = MoverFantasma1(pilha1);
                pilha2 = MoverFantasma2(pilha2);
                pilha3 = MoverFantasma3(pilha3);
                MoverFantasma5();
            } else {
                ghost = RandomMove(ghost);
                ghost1 = RandomMove(ghost1);
                ghost2 = RandomMove(ghost2);
                ghost3 = RandomMove(ghost3);
                ghost5 = RandomMove(ghost5);
                powertime++;
                if (powertime > 25) {
                    powertime = 0;
                    power = false;
                    LoadGhosts();
                }
            }
            reset = Venceu();
            if (reset) {
                stop_sample(siren);
                ghost.x = Posicaoinicial[0].x;
                ghost.y = Posicaoinicial[0].y;
                ghost1.x = Posicaoinicial[1].x;
                ghost1.y = Posicaoinicial[1].y;
                ghost2.x = Posicaoinicial[2].x;
                ghost2.y = Posicaoinicial[2].y;
                ghost3.x = Posicaoinicial[3].x;
                ghost3.y = Posicaoinicial[3].y;
                ghost5.x = Posicaoinicial[4].x;
                ghost5.y = Posicaoinicial[4].y;
                matriz[Ninman.x][Ninman.y] = '0';
                Ninman = player.Pninman;
                matriz[Ninman.x][Ninman.y] = 'p';
                pilha.clear();
                pilha1.clear();
                pilha2.clear();
                pilha3.clear();
                sentido = esquerda;
                if (vida > 0) {
                    Inicio();
                    play_sample(siren, 255, 0, 1000, true);
                }
            }
            tempo = 0;
        }
        if (key[KEY_ESC]) {
            stop_sample(siren);
            GameOptions();
            play_sample(siren, 255, 0, 1000, true);
        }
    }
    conf.RefreshScore(pontos, player.nome);
}

void NinmanGame::DeleteFruit() {
    for (int a = 0; a < linhas; a++) {
        for (int b = 0; b < colunas; b++) {
            if (matriz[a][b] == 'x') {
                matriz[a][b] = '0';
            }
        }
    }
}

void NinmanGame::Inicio() {
    DrawLab();
    BITMAP * temp = load_bitmap("Imagens/GetReady.bmp", NULL);
    draw_sprite(screen, temp, 200, 300 - 43);
    destroy_bitmap(temp);
    SAMPLE * abertura = load_sample("Sound/opening_song.wav");
    play_sample(abertura, 255, 0, 1000, 0);
    rest(5000);

}

void NinmanGame::LoadMatriz() {
    std::ifstream x;
    x.open("Labirintos/player.txt");
    matriz = new std::string [linhas];
    if (x.is_open()) {
        for (int i = 0; i < linhas; i++) {
            getline(x, matriz[i]);
        }
    }
    x.close();
}

void NinmanGame::NewFruit() {
    int x = rand() % linhas, y = rand() % colunas;
    while (matriz[x][y] != '0') {
        x = rand() % linhas;
        y = rand() % colunas;
    }
    matriz[x][y] = 'x';
}

std::list <NinmanGame::PONTO> NinmanGame::MoverFantasma1(std::list <PONTO> pilha1) {
    int a, b;
    a = ghost1.x;
    b = ghost1.y;
    bool achou = false;
    int lastmove = 0;
    bool moveu = true;
    std::list <PONTO> ban;
    if (pilha1.size() < 2) {
        pilha1.push_back(valor(a, b));
        while (moveu && !achou) {
            moveu = false;
            if (b > 0) {
                if (matriz[a][b - 1] != '1' && lastmove != direita && !banlist(ban, a, b - 1)) {
                    b--;
                    if (!banlist(pilha1, a, b)) {
                        moveu = true;
                        lastmove = esquerda;
                        pilha1.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        b++;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }
                if (a > 0) {
                    if (matriz[a - 1][b] != '1' && lastmove != desceu && !banlist(ban, a - 1, b)) {
                        a--;
                        if (!banlist(pilha1, a, b)) {
                            lastmove = subiu;
                            pilha1.push_back(valor(a, b));
                            moveu = true;
                        } else {
                            lastmove = 0;
                            a++;
                        }
                        if (matriz[a][b] == 'p')
                            achou = true;
                    }
                }
                if (b < colunas - 1) {
                    if (matriz[a][b + 1] != '1' && lastmove != esquerda && !banlist(ban, a, b + 1)) {
                        b++;
                        if (!banlist(pilha1, a, b)) {
                            lastmove = direita;
                            moveu = true;
                            pilha1.push_back(valor(a, b));
                        } else {
                            lastmove = 0;
                            b--;
                        }
                        if (matriz[a][b] == 'p') {
                            achou = true;
                        }
                    }
                }
                if (a < linhas - 1) {
                    if (matriz[a + 1][b] != '1' && !banlist(ban, a + 1, b) && lastmove != subiu) {
                        a++;
                        if (!banlist(pilha1, a, b)) {
                            lastmove = desceu;
                            moveu = true;
                            pilha1.push_back(valor(a, b));
                        } else {
                            lastmove = 0;
                            a--;
                        }
                        if (matriz[a][b] == 'p')
                            achou = true;
                    }
                }
            }

            if (moveu == false && !pilha1.empty()) {
                int a0, a1;
                a0 = pilha1.back().x;
                a1 = pilha1.back().y;
                ban.push_back(valor(a0, a1));
                moveu = true;
                if (!pilha1.empty()) {
                    pilha1.pop_back();
                    if (!pilha1.empty()) {
                        a = pilha1.back().x;
                        b = pilha1.back().y;
                    }
                }
            }
        }
    }
    if (!pilha1.empty()) {
        pilha1.pop_front();
        ghost1.x = pilha1.front().x;
        ghost1.y = pilha1.front().y;
    }
    return pilha1;
}

std::list <NinmanGame::PONTO> NinmanGame::MoverFantasma3(std::list <PONTO> pilha3) {
    int a, b;
    a = ghost3.x;
    b = ghost3.y;
    bool achou = false;
    int lastmove = 0;
    bool moveu = true;
    std::list <PONTO> ban;
    if (pilha3.size() < 2) {
        pilha3.push_back(valor(a, b));
        while (moveu && !achou) {
            moveu = false;
            if (b > 0) {
                if (matriz[a][b - 1] != '1' && lastmove != direita && !banlist(ban, a, b - 1)) {
                    b--;
                    if (!banlist(pilha3, a, b)) {
                        moveu = true;
                        lastmove = esquerda;
                        pilha3.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        b++;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }
                if (a < linhas - 1) {
                    if (matriz[a + 1][b] != '1' && !banlist(ban, a + 1, b) && lastmove != subiu) {
                        a++;
                        if (!banlist(pilha3, a, b)) {
                            lastmove = desceu;
                            moveu = true;
                            pilha3.push_back(valor(a, b));
                        } else {
                            lastmove = 0;
                            a--;
                        }
                        if (matriz[a][b] == 'p')
                            achou = true;
                    }
                }
            }

            if (b < colunas - 1) {
                if (matriz[a][b + 1] != '1' && lastmove != esquerda && !banlist(ban, a, b + 1)) {
                    b++;
                    if (!banlist(pilha3, a, b)) {
                        lastmove = direita;
                        moveu = true;
                        pilha3.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        b--;
                    }
                    if (matriz[a][b] == 'p') {
                        achou = true;
                    }
                }
            }
            if (a > 0) {
                if (matriz[a - 1][b] != '1' && lastmove != desceu && !banlist(ban, a - 1, b)) {
                    a--;
                    if (!banlist(pilha3, a, b)) {
                        lastmove = subiu;
                        pilha3.push_back(valor(a, b));
                        moveu = true;
                    } else {
                        lastmove = 0;
                        a++;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }
            }



            if (moveu == false && !pilha3.empty()) {
                int a0, a1;
                a0 = pilha3.back().x;
                a1 = pilha3.back().y;
                ban.push_back(valor(a0, a1));
                moveu = true;
                if (!pilha3.empty()) {
                    pilha3.pop_back();
                    if (!pilha3.empty()) {
                        a = pilha3.back().x;
                        b = pilha3.back().y;
                    }
                }
            }
        }
    }
    if (!pilha3.empty()) {
        pilha3.pop_front();
        ghost3.x = pilha3.front().x;
        ghost3.y = pilha3.front().y;
    }
    return pilha3;
}

std::list <NinmanGame::PONTO> NinmanGame::MoverFantasma(std::list <PONTO> pilha) {
    int a, b;
    a = ghost.x;
    b = ghost.y;
    bool achou = false;
    int lastmove = 0;
    bool moveu = true;
    std::list <PONTO> ban;
    if (pilha.size() < 2) {
        pilha.push_back(valor(a, b));
        while (moveu && !achou) {
            moveu = false;
            if (b < colunas - 1) {
                if (matriz[a][b + 1] != '1' && lastmove != esquerda && !banlist(ban, a, b + 1)) {
                    b++;
                    if (!banlist(pilha, a, b)) {
                        lastmove = direita;
                        moveu = true;
                        pilha.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        b--;
                    }
                    if (matriz[a][b] == 'p') {
                        achou = true;
                    }
                }
            }
            if (a < linhas - 1) {
                if (matriz[a + 1][b] != '1' && !banlist(ban, a + 1, b) && lastmove != subiu) {
                    a++;
                    if (!banlist(pilha, a, b)) {
                        lastmove = desceu;
                        moveu = true;
                        pilha.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        a--;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }
            }
            if (b > 0) {
                if (matriz[a][b - 1] != '1' && lastmove != direita && !banlist(ban, a, b - 1)) {
                    b--;
                    if (!banlist(pilha, a, b)) {
                        moveu = true;
                        lastmove = esquerda;
                        pilha.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        b++;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }
            }
            if (a > 0) {
                if (matriz[a - 1][b] != '1' && lastmove != desceu && !banlist(ban, a - 1, b)) {
                    a--;
                    if (!banlist(pilha, a, b)) {
                        lastmove = subiu;
                        pilha.push_back(valor(a, b));
                        moveu = true;
                    } else {
                        lastmove = 0;
                        a++;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }
            }
            if (moveu == false && !pilha.empty()) {
                int a0, a1;
                a0 = pilha.back().x;
                a1 = pilha.back().y;
                ban.push_back(valor(a0, a1));
                moveu = true;
                if (!pilha.empty()) {
                    pilha.pop_back();
                    if (!pilha.empty()) {
                        a = pilha.back().x;
                        b = pilha.back().y;
                    }
                }
            }
        }
    }
    if (!pilha.empty()) {
        pilha.pop_front();
        ghost.x = pilha.front().x;
        ghost.y = pilha.front().y;
    }
    return pilha;
}

std::list <NinmanGame::PONTO> NinmanGame::MoverFantasma2(std::list <PONTO> pilha2) {
    int a, b;
    a = ghost2.x;
    b = ghost2.y;
    bool achou = false;
    int lastmove = 0;
    bool moveu = true;
    std::list <PONTO> ban;
    if (pilha2.size() < 2) {
        pilha2.push_back(valor(a, b));
        while (moveu && !achou) {
            moveu = false;
            if (b < colunas - 1) {
                if (matriz[a][b + 1] != '1' && lastmove != esquerda && !banlist(ban, a, b + 1)) {
                    b++;
                    if (!banlist(pilha2, a, b)) {
                        lastmove = direita;
                        moveu = true;
                        pilha2.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        b--;
                    }
                    if (matriz[a][b] == 'p') {
                        achou = true;
                    }
                }
            }
            if (a > 0) {
                if (matriz[a - 1][b] != '1' && lastmove != desceu && !banlist(ban, a - 1, b)) {
                    a--;
                    if (!banlist(pilha2, a, b)) {
                        lastmove = subiu;
                        pilha2.push_back(valor(a, b));
                        moveu = true;
                    } else {
                        lastmove = 0;
                        a++;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }
            }
            if (b > 0) {
                if (matriz[a][b - 1] != '1' && lastmove != direita && !banlist(ban, a, b - 1)) {
                    b--;
                    if (!banlist(pilha2, a, b)) {
                        moveu = true;
                        lastmove = esquerda;
                        pilha2.push_back(valor(a, b));
                    } else {
                        lastmove = 0;
                        b++;
                    }
                    if (matriz[a][b] == 'p')
                        achou = true;
                }


                if (a < linhas - 1) {
                    if (matriz[a + 1][b] != '1' && !banlist(ban, a + 1, b) && lastmove != subiu) {
                        a++;
                        if (!banlist(pilha2, a, b)) {
                            lastmove = desceu;
                            moveu = true;
                            pilha2.push_back(valor(a, b));
                        } else {
                            lastmove = 0;
                            a--;
                        }
                        if (matriz[a][b] == 'p')
                            achou = true;
                    }
                }
            }

            if (moveu == false && !pilha2.empty()) {
                int a0, a1;
                a0 = pilha2.back().x;
                a1 = pilha2.back().y;
                ban.push_back(valor(a0, a1));
                moveu = true;
                if (!pilha2.empty()) {
                    pilha2.pop_back();
                    if (!pilha2.empty()) {
                        a = pilha2.back().x;
                        b = pilha2.back().y;
                    }
                }
            }
        }
    }
    if (!pilha2.empty()) {
        pilha2.pop_front();
        ghost2.x = pilha2.front().x;
        ghost2.y = pilha2.front().y;
    }
    return pilha2;
}

void NinmanGame::GameOptions() {

    int y = 220;
    DrawOptions(y);
    while (true) {
        clear_keybuf();
        readkey();
        if (key[KEY_DOWN]) {
            y = y + 55;
            {
                if (y > 330)
                    y = 220;
            }
        }
        if (key[KEY_UP]) {
            y = y - 55;
            {
                if (y < 220)
                    y = 330;
            }
        }
        if (key[KEY_ENTER]) {
            if (y == 275) {
                SaveGame();
                venceu = -2;
            }
            if (y == 330) {
                DestroyerPlayer();
                venceu = -2;
            }
            break;
        }
        DrawOptions(y);
    }
}

void NinmanGame::DestroyerPlayer() {
    std::ofstream y;
    y.open("Player.dat", std::ios::binary);
    player.points = 0;
    y.write((char*) & player, sizeof (player));
    y.close();
}

bool NinmanGame::Venceu() {
    if (!power) {
        if (ghost.x == Ninman.x && ghost.y == Ninman.y) {
            vida--;
            return true;
        }
        if (ghost1.x == Ninman.x && ghost1.y == Ninman.y) {
            vida--;
            return true;
        }
        if (ghost2.x == Ninman.x && ghost2.y == Ninman.y) {
            vida--;
            return true;
        }
        if (ghost3.x == Ninman.x && ghost3.y == Ninman.y) {
            vida--;
            return true;
        }
        if (ghost5.x == Ninman.x && ghost5.y == Ninman.y) {
            vida--;
            return true;
        }
        if (vida == 0) {
            venceu = -1;
        }
    } else {
        if (ghost.x == Ninman.x && ghost.y == Ninman.y)
            EatGhost(0);
        if (ghost1.x == Ninman.x && ghost1.y == Ninman.y)
            EatGhost(1);
        if (ghost2.x == Ninman.x && ghost2.y == Ninman.y)
            EatGhost(2);
        if (ghost3.x == Ninman.x && ghost3.y == Ninman.y)
            EatGhost(3);
        if (ghost5.x == Ninman.x && ghost5.y == Ninman.y)
            EatGhost(4);
    }
    if (CheckWinner())
        venceu = 1;
    return false;
}

NinmanGame::PONTO NinmanGame::RandomMove(PONTO Ghost) {

    int iSecret = rand() % 4;
    switch (iSecret) {
        case 0:
            iSecret = subiu;
            break;
        case 1:
            iSecret = desceu;
            break;
        case 2:
            iSecret = direita;
            break;
        case 3:
            iSecret = esquerda;
            break;
    }

    int sentido2 = iSecret;
    if (sentido2 == direita) {
        if (Ghost.y + 1 < colunas) {
            if (matriz[Ghost.x][Ghost.y + 1] == '1') {
                sentido2 = 0;
            }
        }
    }

    if (sentido2 == subiu) {
        if (Ghost.x - 1 >= 0) {
            if (matriz[Ghost.x - 1][Ghost.y] == '1') {
                sentido2 = 0;
            }
        }
    }
    if (sentido2 == esquerda) {
        if (Ghost.y - 1 >= 0) {
            if (matriz[Ghost.x][Ghost.y - 1] == '1') {
                sentido2 = 0;
            }
        }
    }
    if (sentido2 == desceu) {
        if (Ghost.x < linhas) {
            if (matriz[Ghost.x + 1][Ghost.y] == '1') {
                sentido2 = 0;
            }
        }
    }

    if (sentido2 == 0)
        sentido2 = iSecret;

    if (sentido2 == direita) {
        if (Ghost.y + 1 < colunas) {
            if (matriz[Ghost.x][Ghost.y + 1] != '1') {
                matriz[Ghost.x][Ghost.y] = '0';
                Ghost.y = Ghost.y + 1;
                if (Ghost.y == colunas - 1)
                    Ghost.y = 0;


            }
        }
    }

    if (sentido2 == subiu) {
        if (Ghost.x - 1 >= 0) {
            if (matriz[Ghost.x - 1][Ghost.y] != '1') {
                Ghost.x = Ghost.x - 1;
                if (Ghost.x == 0)
                    Ghost.x = linhas - 1;

            }
        }
    }
    if (sentido2 == esquerda) {
        if (Ghost.y - 1 >= 0) {
            if (matriz[Ghost.x][Ghost.y - 1] != '1') {
                Ghost.y = Ghost.y - 1;
                if (Ghost.y == 0)
                    Ghost.y = colunas - 1;
            }
        }
    }
    if (sentido2 == desceu) {
        if (Ghost.x < linhas) {
            if (matriz[Ghost.x + 1][Ghost.y] != '1') {
                Ghost.x = Ghost.x + 1;
                if (Ghost.x == linhas - 1)
                    Ghost.x = 0;
            }
        }
    }
    return Ghost;
}

void NinmanGame::EatGhost(int x) {
    switch (x) {
        case 0:
            Bit_ghost = load_bitmap("Imagens/eyes.bmp", NULL);
            break;
        case 1:
            Bit_ghost1 = load_bitmap("Imagens/eyes.bmp", NULL);
            break;
        case 2:
            Bit_ghost2 = load_bitmap("Imagens/eyes.bmp", NULL);
            break;
        case 3:
            Bit_ghost3 = load_bitmap("Imagens/eyes.bmp", NULL);
            break;
        case 4:
            Bit_ghost5 = load_bitmap("Imagens/eyes.bmp", NULL);
            break;


    }
}

void NinmanGame::SaveMatriz() {
    std::ofstream x;
    x.open("Labirintos/player.txt");
    if (x.is_open()) {
        for (int i = 0; i < linhas; i++) {
            x << matriz[i] << std::endl;
        }
    }
    x.close();
}

void NinmanGame::SaveGame() {
    std::ofstream y;
    y.open("Player.dat", std::ios::binary);
    player.points = pontos;
    SaveMatriz();
    player.ghost = ghost;
    player.ghost1 = ghost1;
    player.ghost2 = ghost2;
    player.power = power;
    player.ghost3 = ghost3;
    player.ghost5 = ghost5;
    player.colunas = colunas;
    player.linhas = linhas;
    player.sentido = sentido;
    player.powertime = powertime;
    player.vida = vida;
    player.power = power;
    y.write((char*) & player, sizeof (player));
    y.close();

}

void NinmanGame::DrawOptions(int y) {
    DrawLab();
    BITMAP * pacman;
    BITMAP * menu;
    menu = load_bitmap("Imagens/GameMenu.bmp", NULL);
    pacman = load_bitmap("Imagens/pacman.bmp", NULL);
    draw_sprite(screen, menu, 400 - 163, 350 - 153);
    draw_sprite(screen, pacman, 215, y);
    destroy_bitmap(menu);
    destroy_bitmap(pacman);
}

void NinmanGame::LoadPlayer() {
    std::ifstream x;
    x.open("Player.dat", std::ios::binary);
    if (x.is_open()) {
        x.read((char*) & player, sizeof (player));
    }
    x.close();
}

const char* NinmanGame::GetLab(PLAYER player) {
    std::string temp;
    temp = "Labirintos/";
    temp += player.lab;
    temp += ".txt";
    return temp.c_str();
}

bool NinmanGame::CheckWinner() {
    bool venceu = true;
    for (int a = 0; a < linhas; a++) {
        for (int b = 0; b < colunas; b++) {
            if (matriz[a][b] == '2') {
                return false;
            }
        }
    }
    return venceu;
}

NinmanGame::PONTO * NinmanGame::FindGhost() {
    PONTO * temp = new PONTO [5];
    for (int a = 0; a < linhas; a++) {
        for (int b = 0; b < colunas; b++) {

            if (matriz[a][b] == 'g') {
                ghost.x = a;
                ghost.y = b;
                temp[0].x = a;
                temp[0].y = b;
                matriz[a][b] = 0;
            }
            if (matriz[a][b] == 'h') {
                ghost1.x = a;
                ghost1.y = b;
                temp[1].x = a;
                temp[1].y = b;
                matriz[a][b] = 0;
            }
            if (matriz[a][b] == 'j') {
                ghost2.x = a;
                ghost2.y = b;
                temp[2].x = a;
                temp[2].y = b;
                matriz[a][b] = 0;
            }
            if (matriz[a][b] == 'k') {
                ghost3.x = a;
                ghost3.y = b;
                temp[3].x = a;
                temp[3].y = b;
                matriz[a][b] = 0;
            }
            if (matriz[a][b] == 'l') {
                ghost5.x = a;
                ghost5.y = b;
                temp[4].x = a;
                temp[4].y = b;
                matriz[a][b] = 0;
            }
        }
    }
    return temp;
}

NinmanGame::PONTO NinmanGame::procurarNinman() {
    PONTO temp;
    for (int a = 0; a < linhas; a++) {
        for (int b = 0; b < colunas; b++) {
            if (matriz[a][b] == 'p') {
                temp.x = a;
                temp.y = b;
                return temp;
            }
        }
    }
    return valor(0,0);
}

int NinmanGame::Mover(int NextMove) {
    SAMPLE * cumeu = load_sample("Sound/eating.short.wav");
    if (NextMove == direita) {
        if (Ninman.y + 1 < colunas) {
            if (matriz[Ninman.x][Ninman.y + 1] != '1') {
                sentido = direita;
                NextMove = 0;
            }
        }
    }

    if (NextMove == subiu) {
        if (Ninman.x - 1 >= 0) {
            if (matriz[Ninman.x - 1][Ninman.y] != '1') {
                sentido = subiu;
                NextMove = 0;
            }
        }
    }
    if (NextMove == esquerda) {
        if (Ninman.y - 1 >= 0) {
            if (matriz[Ninman.x][Ninman.y - 1] != '1') {
                sentido = esquerda;
                NextMove = 0;
            }
        }
    }
    if (NextMove == desceu) {
        if (Ninman.x < linhas) {
            if (matriz[Ninman.x + 1][Ninman.y] != '1') {
                sentido = desceu;
                NextMove = 0;
            }
        }
    }


    if (sentido == direita) {
        if (Ninman.y + 1 < colunas) {
            if (matriz[Ninman.x][Ninman.y + 1] != '1') {
                matriz[Ninman.x][Ninman.y] = '0';
                Ninman.y = Ninman.y + 1;
                if (matriz[Ninman.x][Ninman.y] == '3')
                    PowerOn();
                if (matriz[Ninman.x][Ninman.y] == 'x')
                    pontos = pontos + 150;
                if (matriz[Ninman.x][Ninman.y] == '2') {
                    pontos = pontos + 10;
                    play_sample(cumeu, 255, 0, 1000, 0);
                }
                if (Ninman.y == colunas - 1)
                    Ninman.y = 0;
                matriz[Ninman.x][Ninman.y] = 'p';

            }
        }
    }

    if (sentido == subiu) {
        if (Ninman.x - 1 >= 0) {
            if (matriz[Ninman.x - 1][Ninman.y] != '1') {
                matriz[Ninman.x][Ninman.y] = '0';
                Ninman.x = Ninman.x - 1;
                if (matriz[Ninman.x][Ninman.y] == '2') {
                    pontos = pontos + 10;
                    play_sample(cumeu, 255, 0, 1000, 0);
                }
                if (matriz[Ninman.x][Ninman.y] == '3')
                    PowerOn();
                if (matriz[Ninman.x][Ninman.y] == 'x')
                    pontos = pontos + 150;
                if (Ninman.x == 0)
                    Ninman.x = linhas - 1;
                matriz[Ninman.x][Ninman.y] = 'p';
            }
        }
    }
    if (sentido == esquerda) {
        if (Ninman.y - 1 >= 0) {
            if (matriz[Ninman.x][Ninman.y - 1] != '1') {
                matriz[Ninman.x][Ninman.y] = '0';
                Ninman.y = Ninman.y - 1;
                if (matriz[Ninman.x][Ninman.y] == '2') {
                    play_sample(cumeu, 255, 0, 1000, 0);
                }
            }
            pontos = pontos + 10;
            if (matriz[Ninman.x][Ninman.y] == '3')
                PowerOn();
            if (matriz[Ninman.x][Ninman.y] == 'x')
                pontos = pontos + 150;
            if (Ninman.y == 0)
                Ninman.y = colunas - 1;
            matriz[Ninman.x][Ninman.y] = 'p';
        }
    }

    if (sentido == desceu) {
        if (Ninman.x < linhas) {
            if (matriz[Ninman.x + 1][Ninman.y] != '1') {
                matriz[Ninman.x][Ninman.y] = '0';

                Ninman.x = Ninman.x + 1;
                if (matriz[Ninman.x][Ninman.y] == '2') {
                    pontos = pontos + 10;
                    play_sample(cumeu, 255, 0, 1000, 0);
                }
                if (matriz[Ninman.x][Ninman.y] == '3')
                    PowerOn();
                if (matriz[Ninman.x][Ninman.y] == 'x')
                    pontos = pontos + 150;
                if (Ninman.x == linhas - 1)
                    Ninman.x = 0;
                matriz[Ninman.x][Ninman.y] = 'p';
            }
        }
    }

    return NextMove;
}

void NinmanGame::PowerOn() {
    power = true;
    BITMAP * fanstasmas = load_bitmap("Imagens/Fantasmas.bmp", NULL);
    Bit_ghost = create_bitmap(24, 23);
    blit(fanstasmas, Bit_ghost, 48, 23, 0, 0, 24, 23);
    Bit_ghost1 = create_bitmap(24, 23);
    blit(fanstasmas, Bit_ghost1, 48, 23, 0, 0, 24, 23);
    Bit_ghost2 = create_bitmap(24, 23);
    blit(fanstasmas, Bit_ghost2, 48, 23, 0, 0, 24, 23);
    Bit_ghost3 = create_bitmap(24, 23);
    blit(fanstasmas, Bit_ghost3, 48, 23, 0, 0, 24, 23);
    Bit_ghost5 = create_bitmap(24, 23);
    blit(fanstasmas, Bit_ghost5, 48, 23, 0, 0, 24, 23);
}

void NinmanGame::MoverFantasma5() {
    int iSecret = rand() % 4;
    switch (iSecret) {
        case 0:
            iSecret = subiu;
            break;
        case 1:
            iSecret = desceu;
            break;
        case 2:
            iSecret = direita;
            break;
        case 3:
            iSecret = esquerda;
            break;
    }
    if (sentido2 == 0)
        sentido2 = iSecret;
    if (sentido2 == direita) {
        if (ghost5.y + 1 < colunas) {
            if (matriz[ghost5.x][ghost5.y + 1] == '1') {
                sentido2 = 0;
            }
        }
    }

    if (sentido2 == subiu) {
        if (ghost5.x - 1 >= 0) {
            if (matriz[ghost5.x - 1][ghost5.y] == '1') {
                sentido2 = 0;
            }
        }
    }
    if (sentido2 == esquerda) {
        if (ghost5.y - 1 >= 0) {
            if (matriz[ghost5.x][ghost5.y - 1] == '1') {
                sentido2 = 0;
            }
        }
    }
    if (sentido2 == desceu) {
        if (ghost5.x < linhas) {
            if (matriz[ghost5.x + 1][ghost5.y] == '1') {
                sentido2 = 0;
            }
        }
    }

    if (sentido2 == 0)
        sentido2 = iSecret;

    if (sentido2 == direita) {
        if (ghost5.y + 1 < colunas) {
            if (matriz[ghost5.x][ghost5.y + 1] != '1') {
                matriz[ghost5.x][ghost5.y] = '0';
                ghost5.y = ghost5.y + 1;
                if (ghost5.y == colunas - 1)
                    ghost5.y = 0;


            }
        }
    }

    if (sentido2 == subiu) {
        if (ghost5.x - 1 >= 0) {
            if (matriz[ghost5.x - 1][ghost5.y] != '1') {
                ghost5.x = ghost5.x - 1;
                if (ghost5.x == 0)
                    ghost5.x = linhas - 1;

            }
        }
    }
    if (sentido2 == esquerda) {
        if (ghost5.y - 1 >= 0) {
            if (matriz[ghost5.x][ghost5.y - 1] != '1') {
                ghost5.y = ghost5.y - 1;
                if (ghost5.y == 0)
                    ghost5.y = colunas - 1;
            }
        }
    }
    if (sentido2 == desceu) {
        if (ghost5.x < linhas) {
            if (matriz[ghost5.x + 1][ghost5.y] != '1') {
                ghost5.x = ghost5.x + 1;
                if (ghost5.x == linhas - 1)
                    ghost5.x = 0;
            }
        }
    }
}

void NinmanGame::LoadLab(const char* file_name) {
    std::ifstream arquivo;
    arquivo.open(file_name);
    std::stack <std::string>aux;
    char* linha = new char [1024];
    while (arquivo) {
        arquivo.getline(linha, 1024);
        aux.push(linha);
    }
    aux.pop();
    linhas = aux.size();

    matriz = new std::string [linhas];
    for (int i = linhas - 1; i >= 0; i--) {
        matriz[i] = aux.top();
        aux.pop();
    }
    colunas = matriz[0].size();
    delete linha;
}

void NinmanGame::LoadBitmaps(int x) {
    BITMAP * sprite = load_bitmap("Imagens/Ninman.bmp", NULL);
    int y = -25;
    Ninman_bit.direita1 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.direita1, TRANSPARENTE);
    blit(sprite, Ninman_bit.direita1, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.direita2 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.direita2, TRANSPARENTE);
    blit(sprite, Ninman_bit.direita2, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.direita3 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.direita3, TRANSPARENTE);
    blit(sprite, Ninman_bit.direita3, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.direita4 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.direita4, TRANSPARENTE);
    blit(sprite, Ninman_bit.direita4, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.direita5 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.direita5, TRANSPARENTE);
    blit(sprite, Ninman_bit.direita5, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.direita6 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.direita6, TRANSPARENTE);
    blit(sprite, Ninman_bit.direita6, x, y = y + 25, 3, 3, 21, 21);

    Ninman_bit.baixo1 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.baixo1, TRANSPARENTE);
    blit(sprite, Ninman_bit.baixo1, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.baixo2 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.baixo2, TRANSPARENTE);
    blit(sprite, Ninman_bit.baixo2, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.baixo3 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.baixo3, TRANSPARENTE);
    blit(sprite, Ninman_bit.baixo3, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.baixo4 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.baixo4, TRANSPARENTE);
    blit(sprite, Ninman_bit.baixo4, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.baixo5 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.baixo5, TRANSPARENTE);
    blit(sprite, Ninman_bit.baixo5, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.baixo6 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.baixo6, TRANSPARENTE);
    blit(sprite, Ninman_bit.baixo6, x, y = y + 25, 3, 3, 21, 21);

    Ninman_bit.esquerda1 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.esquerda1, TRANSPARENTE);
    blit(sprite, Ninman_bit.esquerda1, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.esquerda2 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.esquerda2, TRANSPARENTE);
    blit(sprite, Ninman_bit.esquerda2, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.esquerda3 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.esquerda3, TRANSPARENTE);
    blit(sprite, Ninman_bit.esquerda3, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.esquerda4 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.esquerda4, TRANSPARENTE);
    blit(sprite, Ninman_bit.esquerda4, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.esquerda5 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.esquerda5, TRANSPARENTE);
    blit(sprite, Ninman_bit.esquerda5, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.esquerda6 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.esquerda6, TRANSPARENTE);
    blit(sprite, Ninman_bit.esquerda6, x, y = y + 25, 3, 3, 21, 21);

    Ninman_bit.cima1 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.cima1, TRANSPARENTE);
    blit(sprite, Ninman_bit.cima1, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.cima2 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.cima2, TRANSPARENTE);
    blit(sprite, Ninman_bit.cima2, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.cima3 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.cima3, TRANSPARENTE);
    blit(sprite, Ninman_bit.cima3, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.cima4 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.cima4, TRANSPARENTE);
    blit(sprite, Ninman_bit.cima4, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.cima5 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.cima5, TRANSPARENTE);
    blit(sprite, Ninman_bit.cima5, x, y = y + 25, 3, 3, 21, 21);
    Ninman_bit.cima6 = create_bitmap(26, 26);
    clear_to_color(Ninman_bit.cima6, TRANSPARENTE);
    blit(sprite, Ninman_bit.cima6, x, y = y + 25, 3, 3, 21, 21);

    destroy_bitmap(sprite);
}

void NinmanGame::LoadGhosts() {
    BITMAP * fanstasmas = load_bitmap("Imagens/Fantasmas.bmp", NULL);
    Bit_ghost = create_bitmap(26, 26);
    clear_to_color(Bit_ghost, TRANSPARENTE);
    blit(fanstasmas, Bit_ghost, 0, 0, 1, 1, 24, 23);
    Bit_ghost1 = create_bitmap(26, 26);
    clear_to_color(Bit_ghost1, TRANSPARENTE);
    blit(fanstasmas, Bit_ghost1, 24, 0, 1, 1, 24, 23);
    Bit_ghost2 = create_bitmap(26, 26);
    clear_to_color(Bit_ghost2, TRANSPARENTE);
    blit(fanstasmas, Bit_ghost2, 48, 0, 1, 1, 24, 23);
    Bit_ghost3 = create_bitmap(26, 26);
    clear_to_color(Bit_ghost3, TRANSPARENTE);
    blit(fanstasmas, Bit_ghost3, 0, 23, 1, 1, 24, 23);
    Bit_ghost5 = create_bitmap(26, 26);
    clear_to_color(Bit_ghost5, TRANSPARENTE);
    blit(fanstasmas, Bit_ghost5, 24, 23, 1, 1, 24, 23);
}

int NinmanGame::LerMovimento(int NextMove) {
    if (key[KEY_DOWN])
        NextMove = desceu;
    if (key[KEY_UP])
        NextMove = subiu;
    if (key[KEY_LEFT])
        NextMove = esquerda;
    if (key[KEY_RIGHT])
        NextMove = direita;
    return NextMove;
}

void NinmanGame::DrawLab() {
    BITMAP *mapa = create_bitmap(colunas * 26, linhas * 26 + 20);
    BITMAP * bloco = load_bitmap("Imagens/bloco.bmp", NULL);
    BITMAP * bola2 = load_bitmap("Imagens/bola2.bmp", NULL);
    BITMAP * bola = load_bitmap("Imagens/bola.bmp", NULL);
    BITMAP * fruit = load_bitmap("Imagens/fruit.bmp", NULL);
    clear(mapa);
    for (int a = 0; a < colunas; a++) {
        for (int b = 0; b < linhas; b++) {
            if (matriz[b][a] == '1')
                draw_sprite(mapa, bloco, a * 26, b * 26);
            if (matriz[b][a] == '2')
                draw_sprite(mapa, bola2, a * 26, b * 26);
            if (matriz[b][a] == '3')
                draw_sprite(mapa, bola, a * 26, b * 26);
            if (matriz[b][a] == 'x')
                draw_sprite(mapa, fruit, a * 26, b * 26);
            if (b == ghost.x && a == ghost.y)
                draw_sprite(mapa, Bit_ghost, a * 26, b * 26);
            if (b == ghost1.x && a == ghost1.y)
                draw_sprite(mapa, Bit_ghost1, a * 26, b * 26);
            if (b == ghost2.x && a == ghost2.y)
                draw_sprite(mapa, Bit_ghost2, a * 26, b * 26);
            if (b == ghost3.x && a == ghost3.y)
                draw_sprite(mapa, Bit_ghost3, a * 26, b * 26);
            if (b == ghost5.x && a == ghost5.y)
                draw_sprite(mapa, Bit_ghost5, a * 26, b * 26);
            if (matriz[b][a] == 'p') {
                Ninman.x = b;
                Ninman.y = a;
                if (sentido == direita) {
                    switch (p) {
                        case 0:
                            draw_sprite(mapa, Ninman_bit.direita1, a * 26, b * 26);
                            rest(25);
                            break;
                        case 1:
                            draw_sprite(mapa, Ninman_bit.direita2, a * 26, b * 26);
                            rest(25);
                            break;
                        case 2:
                            draw_sprite(mapa, Ninman_bit.direita3, a * 26, b * 26);
                            rest(25);
                            break;
                        case 3:
                            draw_sprite(mapa, Ninman_bit.direita4, a * 26, b * 26);
                            rest(25);
                            break;
                        case 4:
                            draw_sprite(mapa, Ninman_bit.direita5, a * 26, b * 26);
                            rest(25);
                            break;
                        case 5:
                            draw_sprite(mapa, Ninman_bit.direita6, a * 26, b * 26);
                            rest(25);
                            break;
                    }
                }
                if (sentido == esquerda) {
                    switch (p) {
                        case 0:
                            draw_sprite(mapa, Ninman_bit.esquerda1, a * 26, b * 26);
                            rest(25);
                            break;
                        case 1:
                            draw_sprite(mapa, Ninman_bit.esquerda2, a * 26, b * 26);
                            rest(25);
                            break;
                        case 2:
                            draw_sprite(mapa, Ninman_bit.esquerda3, a * 26, b * 26);
                            rest(25);
                            break;
                        case 3:
                            draw_sprite(mapa, Ninman_bit.esquerda4, a * 26, b * 26);
                            rest(25);
                            break;
                        case 4:
                            draw_sprite(mapa, Ninman_bit.esquerda5, a * 26, b * 26);
                            rest(25);
                            break;
                        case 5:
                            draw_sprite(mapa, Ninman_bit.esquerda6, a * 26, b * 26);
                            rest(25);
                            break;
                    }
                }
                if (sentido == subiu) {
                    switch (p) {
                        case 0:
                            draw_sprite(mapa, Ninman_bit.cima1, a * 26, b * 26);
                            rest(25);
                            break;
                        case 1:
                            draw_sprite(mapa, Ninman_bit.cima2, a * 26, b * 26);
                            rest(25);
                            break;
                        case 2:
                            draw_sprite(mapa, Ninman_bit.cima3, a * 26, b * 26);
                            rest(25);
                            break;
                        case 3:
                            draw_sprite(mapa, Ninman_bit.cima4, a * 26, b * 26);
                            rest(25);
                            break;
                        case 4:
                            draw_sprite(mapa, Ninman_bit.cima5, a * 26, b * 26);
                            rest(25);
                            break;
                        case 5:
                            draw_sprite(mapa, Ninman_bit.cima6, a * 26, b * 26);
                            rest(25);
                            break;
                    }
                }
                if (sentido == desceu) {
                    switch (p) {
                        case 0:
                            draw_sprite(mapa, Ninman_bit.baixo1, a * 26, b * 26);
                            rest(25);
                            break;
                        case 1:
                            draw_sprite(mapa, Ninman_bit.baixo2, a * 26, b * 26);
                            rest(25);
                            break;
                        case 2:
                            draw_sprite(mapa, Ninman_bit.baixo3, a * 26, b * 26);
                            rest(25);
                            break;
                        case 3:
                            draw_sprite(mapa, Ninman_bit.baixo4, a * 26, b * 26);
                            rest(25);
                            break;
                        case 4:
                            draw_sprite(mapa, Ninman_bit.baixo5, a * 26, b * 26);
                            rest(25);
                            break;
                        case 5:
                            draw_sprite(mapa, Ninman_bit.baixo6, a * 26, b * 26);
                            break;
                    }
                }
            }
        }
    }
    char msg[1024];
    char * temp = new char [32];
    memset(msg, 0, 1024);
    strcpy(msg, "Pontos: ");
    memset(temp, 0, 32);
    NinmanConfig::itoa(pontos, temp, 10);
    strcat(msg, temp);
    memset(temp, 0, 32);
    strcat(msg, "          Vidas:");
    NinmanConfig::itoa(vida, temp, 10);
    strcat(msg, temp);
    textout_centre_ex(mapa, font, msg, (colunas * 26 / 2), linhas * 26 + 5, 255, -1);
    draw_sprite(screen, mapa, 400 - (colunas * 26 / 2), 300 - (linhas * 26 / 2) - 5);
    destroy_bitmap(mapa);
    destroy_bitmap(bola);
    destroy_bitmap(bola2);
    destroy_bitmap(fruit);
    destroy_bitmap(bloco);
}

bool NinmanGame::banlist(std::list <PONTO> ban, int a, int b) {
    std::list <PONTO> aux;
    int temp1, temp;
    bool resposta = false;
    while (!ban.empty()) {
        temp = ban.back().x;
        temp1 = ban.back().y;
        aux.push_back(valor(temp, temp1));
        ban.pop_back();
        if (temp == a && temp1 == b) {
            resposta = true;
        }
    }
    while (!aux.empty()) {
        temp = aux.back().x;
        temp1 = aux.back().y;
        ban.push_back(valor(temp, temp1));
        aux.pop_back();

    }
    return resposta;
}
